package com.mcxiaoke.next.samples;
import android.content.Context;
import android.support.v4.view.MotionEventCompat;
import android.util.AttributeSet;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.widget.AbsListView;
import com.mcxiaoke.next.ui.endless.EndlessListView;
/**
* User: mcxiaoke
* Date: 13-11-26
* Time: 下午4:06
*/
public class MotionTrackListView extends EndlessListView {
public static final boolean DEBUG = true;
public static final String TAG = MotionTrackListView.class.getSimpleName();
public static final int CHECK_DISTANCE_MIN = 5;
public static final int CHECK_DISTANCE_MAX = 50;
public interface ScrollCallback {
void onFlingUp(int distanceY);
void onFlingDown(int distanceY);
void onScroll(float distance, float delta);
void onUp(float distance);
}
private GestureDetector mDetector;
private ScrollCallback mScrollCallback;
public MotionTrackListView(Context context) {
super(context);
initialize(context);
}
public MotionTrackListView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initialize(context);
}
public MotionTrackListView(Context context, AttributeSet attrs) {
super(context, attrs);
initialize(context);
}
private void initialize(Context context) {
mDetector = new GestureDetector(context, new UpDownGestureDetector());
mDetector.setIsLongpressEnabled(false);
}
public void setScrollCallback(ScrollCallback callback) {
mScrollCallback = callback;
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
int action = MotionEventCompat.getActionMasked(ev);
switch (action) {
case MotionEvent.ACTION_DOWN:
break;
case MotionEvent.ACTION_MOVE:
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
break;
default:
break;
}
return super.onInterceptTouchEvent(ev);
}
private float mTranslateY;
private float mLastTouchY;
private float mLastY;
@Override
public boolean onTouchEvent(MotionEvent ev) {
int index = ev.getActionIndex();
int action = ev.getActionMasked();
int pointerId = ev.getPointerId(index);
switch (action) {
case MotionEvent.ACTION_DOWN:
float downY = ev.getRawY();
mTranslateY = 0;
mLastTouchY = downY;
mLastY = downY;
if (DEBUG) {
Log.v(TAG, "ACTION_DOWN mLastY=" + mLastY);
}
break;
case MotionEvent.ACTION_MOVE:
float currentY = ev.getRawY();
float delta = currentY - mLastY;
mTranslateY += delta;
mLastY = currentY;
if (DEBUG) {
Log.v(TAG, "ACTION_MOVE currentY=" + currentY + " mTranslateY=" + mTranslateY);
Log.v(TAG, "ACTION_MOVE delta=" + delta);
}
if (mScrollCallback != null) {
mScrollCallback.onScroll(mTranslateY, delta);
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
float endY = ev.getRawY();
if (DEBUG) {
Log.v(TAG, "ACTION_UP endY=" + endY + " mTranslateY=" + mTranslateY);
}
if (mScrollCallback != null) {
mScrollCallback.onUp(endY - mLastTouchY);
}
mLastTouchY = 0;
mLastY = 0;
mTranslateY = 0;
break;
default:
break;
}
mDetector.onTouchEvent(ev);
return super.onTouchEvent(ev);
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
super.onScroll(view, firstVisibleItem, visibleItemCount, totalItemCount);
}
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
super.onScrollStateChanged(view, scrollState);
}
@Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
super.onScrollChanged(l, t, oldl, oldt);
}
class UpDownGestureDetector extends GestureDetector.SimpleOnGestureListener {
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
float y1 = e1 == null ? -1 : e1.getRawY();
float y2 = e2 == null ? -1 : e2.getRawY();
if (DEBUG) {
Log.v(TAG, "onFling() y1=" + y1 + " y2=" + y2);
Log.v(TAG, "onFling() velocityY=" + velocityY);
}
return super.onFling(e1, e2, velocityX, velocityY);
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
boolean ret = super.onScroll(e1, e2, distanceX, distanceY);
float y1 = e1 == null ? -1 : e1.getY();
float y2 = e2 == null ? -1 : e2.getY();
if (DEBUG) {
Log.v(TAG, "onScroll() y1=" + y1 + " y2=" + y2);
Log.v(TAG, "onScroll() distanceY=" + distanceY);
}
int dy = (int) distanceY;
int dyAbs = Math.abs(dy);
if (dyAbs < CHECK_DISTANCE_MIN || dyAbs > CHECK_DISTANCE_MAX) {
return ret;
}
return ret;
}
}
}